#ifndef FRACTION_H_
#define FRACTION_H_
#include "Integers.h" 
#include <iostream>
namespace SymCe{

	class Fraction{
		/* Stores number as an (irreducible) fraction.
		 * Numerator and Denominator are of Integer type,
		 * which is unsigned int, but can be replaced by multiprecision integers if needed.
		 * Do we allow Fractions with zero denominator?
		 */
		public:
		private:
		Integer p;	//Numenator
		Integer q;	//Denominator
		/*Numerator and denominator are called p and q respectively, because it is
		 * short and these are most frequent letters to represent them.
		 */
		 Sign sign;	//Both p and q are unsigned, so we need sign for the Fraction; true is for negative. 
		 /* No more data needed.
		  * Now we need operators so that fraction acts as any other plain data type in C.
		  * Needed operators: + - (both unary and binary) * / < > <= >= == != and all kinds of = and conversions.
		  * We do not need ++/--, % or any other.
		  * Constructor destructor and = operator from compiler could be enough, but it would be nice to add more constructors.
		  * And we need to print out the Fraction somehow.
		  */
		  public:
		  //All functions are defined in Fraction.cpp Here are only declarations.
		  //Constructors and conversions
		  Fraction();
		  Fraction(const Fraction & fraction);
		  Fraction(Sign sign_, Integer p_, Integer q_);
		  Fraction(int p_, int q_);
		  Fraction(int i_);	//Is it enough? What about other types of integers?
		  //More?
		  
		  //Destructor
		  ~Fraction();
		  
		  //Operators
		  //Unary:
		  Fraction operator+(void) const;
		  Fraction operator-(void) const;
		  //We definitely need +, -, * and / with another Fractions. Maybe too with integer types,
		  //but integers can be converted to Fractions.
		  //Binary:
		  Fraction operator+(const Fraction &) const;
		  Fraction operator-(const Fraction &) const;
		  Fraction operator*(const Fraction &) const;
		  Fraction operator/(const Fraction &) const;
		  Fraction & operator=(const Fraction &);	//TODO: Other assignments?
		  //Comparison:
		  bool operator<(const Fraction &) const;
		  bool operator>(const Fraction &) const;
		  bool operator<=(const Fraction &) const;
		  bool operator>=(const Fraction &) const;
		  bool operator==(const Fraction &) const;
		  bool operator!=(const Fraction &) const;
		  //Getting the values of data.
		  bool is_negative(void) const;
		  bool is_positive(void) const;
		  Integer get_numerator(void) const;
		  Integer get_denominator(void) const;
		  //Conversions will be added later.
		  void reduce(void); //Can be made private, because fraction should always be reduced.
		  Fraction opposite(void) const; //returns opposite number (just reversed sign)
		  Fraction inverted(void) const; //returns inverted fraction (changed p and q)
		  //We need to be able to send fraction to ostream and convert fraction to integer.
	};
	std::ostream & operator<<(std::ostream & s, const Fraction & fraction);
}

#endif /*FRACTION_H_*/
